﻿package org.abc.utils
{
	import flash.display.*;
	import flash.filters.*;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.FileFilter;
	import flash.utils.ByteArray;

	/**
	 * 图片处理类，支持黑白，亮度，对比度，饱和度，单色，柔化，还原，去红眼，魔棒，切图，球面效果,反色,灰度,查找边缘, 锐化
	 * @author aishi
	 *
	 */
	public class EffectUtil
	{
		/**
		 * 设置白色滤镜
		 * @param child
		 *
		 */
		public static function setWhiteGlowFilter(child:Sprite):void
		{
			var gradientGlow:GradientGlowFilter=new GradientGlowFilter(0, 45, [0xffffff, 0xFFffff], [0, 1], [0, 255], 2, 2, 100, 3, "outer");
			child.filters=[gradientGlow]
		}

		/**
		 * 黑白效果
		 * @param child 可视化对象
		 * @return
		 *
		 */
		public static function setGray(child:DisplayObject):void
		{
			var matrix:Array=[0.33, 0.33, 0.33, 0, 0, 0.33, 0.33, 0.33, 0, 0, 0.33, 0.33, 0.33, 0, 0, 0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}

		/**
		 * 亮度调节
		 * @param child 可视化对象
		 * @param val 范围[-100,100]
		 * @return
		 *
		 */
		public static function setBrightness(child:DisplayObject, val:Number):void
		{
			if (isNaN(val))
			{
				return;
			}
			val=limitPara(val);
			var matrix:Array=[1, 0, 0, 0, val, 0, 1, 0, 0, val, 0, 0, 1, 0, val, 0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}

		/**
		 * 对比度
		 * @param child 可视化对象
		 * @param val 范围[-255,255]
		 * @return
		 *
		 */
		public static function setContrast(child:DisplayObject, val:Number):void
		{
			if (isNaN(val))
			{
				return;
			}
			val=limitPara(val);
			var DELTA_INDEX=[0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11, 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.2, 0.21, 0.22, 0.24, 0.25, 0.27, 0.28, 0.3, 0.32, 0.34, 0.36, 0.38, 0.4, 0.42, 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68, 0.71, 0.74, 0.77, 0.8, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98, 1, 1.06, 1.12, 1.18, 1.24, 1.3, 1.36, 1.42, 1.48, 1.54, 1.6, 1.66, 1.72, 1.78, 1.84, 1.9, 1.96, 2, 2.12, 2.25, 2.37, 2.5, 2.62, 2.75, 2.87, 3, 3.2, 3.4, 3.6, 3.8, 4, 4.3, 4.7, 4.9, 5, 5.5, 6, 6.5, 6.8, 7, 7.3, 7.5, 7.8, 8, 8.4, 8.7, 9, 9.4, 9.6, 9.8, 10];
			var diffNum;
			if (val < 0)
			{
				diffNum=127 + val / 100 * 127;
			}
			else
			{
				diffNum=val % 1;
				if (diffNum == 0)
				{
					diffNum=DELTA_INDEX[val];
				}
				else
				{
					diffNum=DELTA_INDEX[val << 0] * (1 - diffNum) + DELTA_INDEX[(val << 0) + 1] * diffNum;
				}
				diffNum=diffNum * 127 + 127;
			}
			var matrix:Array=[diffNum / 127, 0, 0, 0, 0.5 * (127 - diffNum), 0, diffNum / 127, 0, 0, 0.5 * (127 - diffNum), 0, 0, diffNum / 127, 0, 0.5 * (127 - diffNum), 0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}

		/**
		 * 饱和度
		 * @param child 可视化对象
		 * @param val 范围[-255,255]
		 * @return
		 *
		 */
		public static function setSaturation(child:DisplayObject, val:Number):void
		{
			if (isNaN(val))
			{
				return;
			}
			val=limitPara(val);
			var diffNum=1 + ((val > 0) ? ((3 * val) / 100) : (val / 100));
			var rr=0.3086;
			var gg=0.6094;
			var bb=0.082;
			var matrix:Array=[rr * (1 - diffNum) + diffNum, gg * (1 - diffNum), bb * (1 - diffNum), 0, 0, rr * (1 - diffNum), gg * (1 - diffNum) + diffNum, bb * (1 - diffNum), 0, 0, rr * (1 - diffNum), gg * (1 - diffNum), bb * (1 - diffNum) + diffNum, 0, 0, 0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}

		/**
		 * 单色
		 * @param child 可视化对象
		 * @param val 范围[-255,255]
		 * @return
		 *
		 */
		public static function setHue(child:DisplayObject, val:Number):void
		{
			val=val / 180 * Math.PI;
			if (isNaN(val))
			{
				return;
			}
			val=limitPara(val);
			var x=Math.cos(val);
			var y=Math.sin(val);
			var rr=0.213;
			var gg=0.715;
			var bb=0.072;
			var matrix:Array=[(rr + (x * (1 - rr))) + (y * (-rr)), (gg + (x * (-gg))) + (y * (-gg)), (bb + (x * (-bb))) + (y * (1 - bb)), 0, 0, (rr + (x * (-rr))) + (y * 0.143), (gg + (x * (1 - gg))) + (y * 0.14), (bb + (x * (-bb))) + (y * -0.283), 0, 0, (rr + (x * (-rr))) + (y * (-(1 - rr))), (gg + (x * (-gg))) + (y * gg), (bb + (x * (1 - bb))) + (y * bb), 0, 0, 0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}

		/**
		 * 柔化
		 * @param child 可视化对象
		 * @param val 范围[-255,255]
		 * @return
		 *
		 */
		public static function setBlur(child:DisplayObject, val:Number):void
		{
			if (isNaN(val))
			{
				return;
			}
			val=Math.min(val, 255);
			val=Math.max(val, 0);
			var blurX:Number=val;
			var blurY:Number=val;
			var filter:BlurFilter=new BlurFilter(blurX, blurY, BitmapFilterQuality.HIGH);
			child.filters=[filter];
		}

		/**
		 * 还原
		 * @param child 可视化对象
		 * @return
		 *
		 */
		public static function reset(child:DisplayObject):void
		{
			var matrix:Array=[1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}

		/**
		 * 去红眼
		 * @param bmd 要处理的图片数据
		 * @param rec 要处理的区域
		 * @return
		 *
		 */
		public static function RedEyeReduction(bmd:BitmapData, rec:Rectangle):void
		{
			bmd.lock();
			for (var i=rec.x - rec.width; i < rec.width + rec.x; i++)
			{
				for (var j=rec.y - rec.height; j < rec.height + rec.y; j++)
				{
					var pix:Number=bmd.getPixel(i, j);
					var rr=pix >>> 16 & 255;
					var gg=pix >>> 8 & 255;
					var bb=pix & 255;
					var rrr=rr * 0.513333;
					var bbb=bb * 0.193333;
					var ggg=gg;
					if (rr >= ggg && rr >= bbb)
					{
						rr=Math.round((ggg + bbb) / (2 * 0.513333));
						if (rr > 255)
						{
							rr=255;
						}
						else if (rr < 0)
						{
							rr=0;
						}
						bmd.setPixel(i, j, rr << 16 | gg << 8 | bb);
					}
				}
			}
			bmd.unlock();
		}

		/**
		 * 切图
		 * @param bmd 要处理的图片数据
		 * @param rec 要切的区域
		 * @return BitmapData
		 *
		 */
		public static function cut(bmd:BitmapData, rec:Rectangle):BitmapData
		{

			if (rec.x + rec.width < 0 || rec.y + rec.height < 0)
			{
				return bmd;
			}
			if (rec.x > bmd.width || rec.y > bmd.height)
			{
				return bmd;
			}

			if (rec.x < 0)
			{
				rec.width+=rec.x;
				rec.x=0;
			}
			if (rec.y < 0)
			{
				rec.height+=rec.y;
				rec.y=0;
			}
			if (rec.x + rec.width > bmd.width)
			{
				rec.width=bmd.width - rec.x;
			}
			if (rec.y + rec.height > bmd.height)
			{
				rec.height=bmd.height - rec.y;
			}
			bmd.lock();
			var tempColor:ByteArray=bmd.getPixels(rec);

			var bmd_:BitmapData=new BitmapData(rec.width, rec.height, true, 0x00FFFF);
			tempColor.position=0;
			bmd_.setPixels(new Rectangle(0, 0, rec.width, rec.height), tempColor);
			bmd.unlock();
			return bmd_;
		}

		/**
		 * 球面效果
		 * @param source 要处理的图片数据
		 * @param midx
		 * @param midy
		 * @return BitmapData
		 *
		 */
		public static function spherizeFilter(bmd:BitmapData, p:Point):BitmapData
		{

			var maxp_xy=Math.max(p.x, p.y);
			var radian, radius, offsetX, offsetY, color, r, g, b;
			var bmd=bmd.clone();
			for (var i=0; i < bmd.height - 1; i++)
			{
				for (var j=0; j < bmd.width - 1; j++)
				{
					offsetX=j - p.x;
					offsetY=i - p.y;
					radian=Math.atan2(offsetY, offsetX);
					radius=(offsetX * offsetX + offsetY * offsetY) / maxp_xy
					var x=int(radius * Math.cos(radian)) + p.x;
					var y=int(radius * Math.sin(radian)) + p.y;
					if (x < 0)
					{
						x=0;
					}
					if (x >= bmd.width)
					{
						x=bmd.width - 1;
					}
					if (y < 0)
					{
						y=0;
					}
					if (y >= bmd.height)
					{
						y=bmd.height - 1;
					}
					color=bmd.getPixel(x, y);
					r=(color & 0xff0000) >> 16;
					g=(color & 0x00ff00) >> 8;
					b=color & 0x0000ff;
					bmd.setPixel(j, i, r * 65536 + g * 256 + b);
				}
			}
			return bmd;
		}


		//改变mc颜色
		public static function ChangeColor(mc:MovieClip, R:Number, G:Number, B:Number):void
		{
			mc.transform.colorTransform=new ColorTransform(0.5, 0.5, 0.5, 1, R, G, B, 0);
		}


		//限定参数val的取值范围为-100--100之间 
		private static function limitPara(val:Number):Number
		{
			val=Math.min(val, 100);
			val=Math.max(val, -100);
			return val;
		}


		/**
		 *  相底反色效果。
		 * @param child 可视化对象
		 * @return
		 *
		 */
		public static function setInvertColors(child:DisplayObject):void
		{
			var matrix:Array=[-1, 0, 0, 0, 255, 0, -1, 0, 0, 255, 0, 0, -1, 0, 255, 0, 0, 0, 1, 1];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}

		/**
		 *  灰度
		 * @param child 可视化对象
		 * @return
		 *
		 */
		public static function setGrayScale(child:DisplayObject):void
		{
			var matrix:Array=[0.3086, 0.6094, 0.0820, 0, 0, 0.3086, 0.6094, 0.0820, 0, 0, 0.3086, 0.6094, 0.0820, 0, 0, 0, 0, 0, 1, 0];
			var filter:ColorMatrixFilter=new ColorMatrixFilter(matrix);
			child.filters=[filter];
		}

		/**
		 *   查找边缘
		 * @param child 可视化对象
		 * @return
		 *
		 */
		public static function setEdge(child:DisplayObject):void
		{
			var matrix:Array=[0, -1, 0, -1, 4, -1, 0, -1, 0];
			var filter:ConvolutionFilter=new ConvolutionFilter(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6], matrix[7], matrix[8]);

			child.filters=[filter];
		}

		/**
		 *   锐化
		 * @param child 可视化对象
		 * @return
		 *
		 */
		public static function setSharpen(child:DisplayObject):void
		{
			var matrix:Array=[0, -1, 0, -1, 5, -1, 0, -1, 0];
			var filter:ConvolutionFilter=new ConvolutionFilter(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5], matrix[6], matrix[7], matrix[8]);
			child.filters=[filter];
		}

		/**
		 * 设置红色发光滤镜
		 *
		 * */
		public static function setRedGlowFilters(child:DisplayObject):void
		{

			var glow:GlowFilter=new GlowFilter();
			glow.color=0xFF0000;
			glow.alpha=1;
			glow.blurX=20;
			glow.blurY=20;
			glow.quality=BitmapFilterQuality.LOW;

			child.filters=[glow];
		}


	}
}
